home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
003
/
roff
/
tpr0.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
11KB
|
547 lines
/*
** tpr - text formatter
** Ken Yap, June 1981
*/
#include "tpr.h"
struct macro macros[MAXMAC];
short maccnt = 0; /* counter for current macro */
char *pbptr[MAXMAC]; /* pointers to pushed back lines */
short pblev = 0; /* indicates level of macro nesting during collection */
char outbuf[MAXOUT]; /* lines to be filled collect here */
char *outp = outbuf; /* last char position in outbuf; init = 0 */
short outw = 0; /* width of text currenty in outbuf; init = 0 */
short outwds = 0; /* number of words in outbuf; init = 0 */
short pages = 1; /* pages between pauses with -s option */
short pausecount= 0; /* decremented every page */
short curpag = 0;
short newpag = 1;
short lineno = 0;
short peekno = 1;
short indline = 0;
short respage = 0;
char trapmac[2] = "";
char blnkhdr[] = "\n";
struct envir env = {
PAGLEN, M1DEF, M2DEF, M3DEF, M4DEF, (PAGLEN-M3DEF-M4DEF),
blnkhdr, blnkhdr,
blnkhdr, blnkhdr,
'.', '\t', ' ',
YES, YES, ARABIC, 1, PAGEWIDTH, 0, 0, 0, 0, 0, 0, 0, 0, 0,
{ 8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,0 },
NULL
};
struct envir *curenv = NULL;
struct cmdents builtins[] ={
{ "ad",YES },
{ "ar",YES },
{ "bd",YES },
{ "bl",YES },
{ "bp",YES },
{ "br",YES },
{ "cc",YES },
{ "ce",YES },
{ "de",YES },
{ "ef",YES },
{ "eg",YES },
{ "eh",YES },
{ "fi",YES },
{ "fo",YES },
{ "he",YES },
{ "in",YES },
{ "ix",YES },
{ "li",YES },
{ "ll",YES },
{ "ls",YES },
{ "m1",YES },
{ "m2",YES },
{ "m3",YES },
{ "m4",YES },
{ "na",YES },
{ "ne",YES },
{ "nf",YES },
{ "of",YES },
{ "oh",YES },
{ "pl",YES },
{ "po",YES },
{ "pt",YES },
{ "re",YES },
{ "rf",YES },
{ "ro",YES },
{ "rp",YES },
{ "se",YES },
{ "sk",YES },
{ "so",YES },
{ "sp",YES },
{ "ta",YES },
{ "tc",YES },
{ "ti",YES },
{ "ub",YES },
{ "ul",YES }
};
short echodir = 0;
char *progname;
char *filename = "stdin";
short fileline = 0;
short ttyfd = -1; /* for pause between pages */
FILE *indfp = NULL;
char *nomem = "Out of dynamic memory\n"; /* canned message */
/*
** main
*/
main(argc,argv)
short argc;
char **argv;{
FILE *file;
#ifdef unix
extern char _sobuf[];
#endif
progname = *argv;
for(argc--, argv++; argc > 0 && **argv == '-' && (*argv)[1] != '\0'; argc--, argv++)
setoptions(*argv);
#ifdef unix
setbuf(stdout,_sobuf);
#endif
if(argc == 0)
tpr(stdin,"stdin");
else
for( ; argc > 0; argc--, argv++){
if(**argv == '-' && (*argv)[1] == '\0')
tpr(stdin,"stdin");
else{
if((file = fopen(*argv,"r")) == NULL){
perror(*argv);
continue;
}
tpr(file,*argv);
fclose(file);
}
}
if(lineno > 0)
spc(HUGE); /* flush last output */
if(indfp != NULL)
fclose(indfp);
fflush(stdout);
}
setoptions(arg)
char *arg;{
register char c;
int isatty(),open();
FILE *fopen();
while((c = *++arg) != '\0')
switch(c){
case 'd': /* echo directives */
echodir++;
break;
case 'e': /* divert errors */
close(2);
if(creat(++arg,0600) < 0){
open("/dev/tty",1);
perror(arg);
exit(1);
}
return;
case 'i': /* open index file */
if((indfp = fopen(arg[1] == '\0' ? "index" : ++arg, "w")) == NULL)
perror(arg);
return;
case 'n': /* set initial page number */
curpag = atoi(++arg);
if(curpag < 0)
curpag = 0;
newpag = curpag;
return;
case 's': /* pause every n pages */
pages = atoi(++arg);
if(pages <= 0)
pages = 1;
pausecount = pages;
#ifdef unix
if(isatty(fileno(stdout)))
ttyfd = open("/dev/tty",0);
#else
ttyfd = fileno (stdout);
#endif
return;
default:
fprintf(stderr,"Usage: %s [-d] [-efile] [-iindex] [-nN] [-sN] files\n",progname);
exit(1);
}
}
/*
** tpr - here is the main routine for each file
** the name is passed along so that the 'include' directive
** can call 'tpr' recursively
*/
tpr(file,name)
FILE *file;
char *name;{
register char *savename;
register short saveline;
char inbuf[MAXIN];
char *ngetl();
savename = filename; /* save old name */
filename = name; /* make new one available for error routine */
saveline = fileline; /* and line number */
fileline = 0;
while(ngetl(inbuf,file) != CHARNULL){
++fileline;
if(*inbuf == env.comchr) /* it's a command */
cmd(inbuf,file);
else /* it's text */
text(inbuf);
}
filename = savename; /* restore name and linenumber */
fileline = saveline;
}
/*
** error - prints filename and linenumber
*/
error(msg,arg)
char *msg,*arg;{
fprintf(stderr,"At line %d in file %s: ",fileline,filename);
fprintf(stderr,msg,arg);
}
/*
** bold - bolden a line
*/
bold(buf,tbuf,tend)
char *buf,*tbuf,*tend;{
register char c;
register char *p,*q;
char *strcpy();
p = buf;
q = tbuf;
while(*p != '\n' && q < tend){
if(isprint(c = *p++)){
*q++ = c;
*q++ = '\b';
}
*q++ = c;
}
*q++ = '\n';
*q = '\0';
strcpy(buf,tbuf); /* copy it back to buf */
}
/*
** blnk - space n lines (to new page if necessary, cf spc)
*/
blnk(n)
short n;{
register short i;
short nextline();
linebreak();
while(n > 0){
if(lineno > env.bottom){
pfoot();
lineno = 0;
peekno = nextline(lineno);
}
if(lineno == 0)
newpage();
i = min(n,env.bottom + 1 - lineno);
skip(i);
n -= i;
lineno += i;
peekno = nextline(lineno);
}
if(lineno > env.bottom)
pfoot();
}
/*
** linebreak - end current filled line
*/
linebreak(){
if(outp != outbuf){
*outp++ = '\n';
*outp = '\0';
put(outbuf);
}
outp = outbuf;
outw = 0;
outwds = 0;
}
/*
** centre - centre a line by setting tival
*/
center(buf)
char *buf;{
short width();
env.tival = max((env.llval + env.tival - width(buf))/2,0);
}
/*
** cmd - perform formatting command
*/
cmd(buf,file)
char *buf;
FILE *file;{
CMDNUM comtyp();
CMDNUM ct;
register short spval,val;
register char *p;
short macnum;
char argtyp;
char fn[MAXFN];
FILE *fp;
int strlen();
short getval(),set();
char *gettl();
if(echodir)
putdir(buf);
ct = comtyp(buf,&macnum);
val = 0;
val = getval(buf,&argtyp);
switch(ct){
case SPA:
spval = set(0,val,argtyp,1,0,HUGE);
spc(spval);
break;
case IND:
case INX:
if(ct == IND)
linebreak();
env.inval = set(env.inval,val,argtyp,0,0,env.llval - 1);
env.tival = env.inval;
break;
case TMI:
linebreak();
env.tival = set(env.tival,val,argtyp,0,0,env.llval);
break;
case CEN:
linebreak();
env.ceval = set(env.ceval,val,argtyp,1,0,HUGE);
break;
case UDL:
env.ulval = set(env.ulval,val,argtyp,0,1,HUGE);
break;
case BLD:
env.bdval = set(env.bdval,val,argtyp,0,1,HUGE);
break;
case FIL:
linebreak();
env.fill = YES;
break;
case NFL:
linebreak();
env.fill = NO;
break;
case BRE:
linebreak();
break;
case BLN:
env.blval = set(env.blval,val,argtyp,1,0,HUGE);
blnk(env.blval);
env.blval = 0;
break;
case NED:
if(val > env.bottom - peekno + 1)
spc(HUGE);
break;
case LNS:
env.lsval = set(env.lsval,val,argtyp,1,1,HUGE);
break;
case LNL:
env.llval = set(env.llval,val,argtyp,PAGEWIDTH,env.tival + 1,HUGE);
break;
case PGL:
env.plval = set(env.plval,val,argtyp,PAGLEN,
env.m1val + env.m2val + env.m3val + env.m4val + 1,HUGE);
env.bottom = env.plval - env.m3val - env.m4val;
break;
case BPG:
if(lineno > 0)
spc(HUGE);
curpag = set(curpag,val,argtyp,curpag + 1, - HUGE,HUGE);
newpag = curpag;
break;
case HED:
env.evenhdr = env.oddhdr = gettl(buf);
break;
case FOT:
env.evenftr = env.oddftr = gettl(buf);
break;
case EHD:
env.evenhdr = gettl(buf);
break;
case EFO:
env.evenftr = gettl(buf);
break;
case OHD:
env.oddhdr = gettl(buf);
break;
case OFO:
env.oddftr = gettl(buf);
break;
case NAD:
env.adjust = NO;
break;
case ADJ:
env.adjust = YES;
break;
case ROM:
env.numtyp = ROMAN;
break;
case ARA:
env.numtyp = ARABIC;
break;
case ENG:
env.numtyp = ENGLISH;
break;
case LIT:
env.litval = set(env.litval,val,argtyp,1,0,HUGE);
break;
case M1:
env.m1val = set(env.m1val,val,argtyp,M1DEF,
0,env.plval - (env.m2val + env.m3val + env.m4val + 1));
break;
case M2:
env.m2val = set(env.m2val,val,argtyp,M2DEF,
0,env.plval - (env.m1val + env.m3val + env.m4val + 1));
break;
case M3:
env.m3val = set(env.m3val,val,argtyp,M3DEF,
0,env.plval - (env.m1val + env.m2val + env.m4val + 1));
env.bottom = env.plval - env.m3val - env.m4val;
break;
case M4:
env.m4val = set(env.m4val,val,argtyp,M4DEF,
0,env.plval - (env.m1val + env.m2val + env.m3val + 1));
env.bottom = env.plval - env.m3val - env.m4val;
break;
case CMC:
if(argtyp != '\n')
env.comchr = argtyp;
else
env.comchr = COMMAND;
break;
case POF:
env.poval = set(env.poval,val,argtyp,0,0,PAPERSIZE);
break;
case SKP:
env.skpval = set(env.skpval,val,argtyp,1,0,HUGE);
break;
case DFN:
getmac(buf,file);
break;
case TCH:
if(argtyp != '\n')
env.tabchr = argtyp;
else
env.tabchr = '\t';
break;
case TCL:
tabcol(buf);
break;
case UBC:
if(argtyp != '\n')
env.ubchr = argtyp;
else
env.ubchr = ' ';
break;
case REF:
if(indfp != NULL)
indline = set(indline,val,argtyp,1,0,HUGE);
break;
case RPG:
respage += set(0,val,argtyp,1,0,HUGE);
break;
case PGT:
settrap(buf);
break;
case RNV:
if(val <= 0)
val = 1;
resenv(val);
break;
case SNV:
savenv();
break;
case MAC:
expand(macnum);
break;
case SOU:
skipnbl(buf);
skipbl(buf);
for(p = fn; p < &fn[MAXFN - 1] && *buf != '\n'; )
*p++ = *buf++;
*p = '\0';
if((fp = fopen(fn,"r")) == NULL)
error("Cannot open %s\n",fn);
else{
tpr(fp,fn);
fclose(fp);
}
break;
case UNKNOWN:
error("Unrecognised directive:\n%s",buf);
return;
}
}
/*
** comtyp - decode command type
*/
CMDNUM comtyp(buf,macnum)
char *buf;
short *macnum;{
register char a,b;
register struct cmdents *p;
register char *q;
register short l,h,m;
a = buf[1];
b = buf[2];
for(l = 0, h = (sizeof(builtins)/sizeof(builtins[0])) - 1; l <= h; ){
p = &builtins[m = (l + h) / 2];
if(a < p->cmdname[0] || a <= p->cmdname[0] && b < p->cmdname[1])
h = m - 1;
else if(a > p->cmdname[0] || a <= p->cmdname[0] && b > p->cmdname[1])
l = m + 1;
else
break;
}
if(l <= h && p->notredefd)
return((CMDNUM)m);
for(l = maccnt - 1; l >= 0; l--){
q = macros[l].macnam;
if(a == *q++ && b == *q){
*macnum = l;
return(MAC);
}
}
return(UNKNOWN);
}
#ifdef AMIGA
perror (arg)
char *arg;
{
if (arg && *arg) {
fprintf (stderr, "%s: ", arg);
}
fprintf (stderr, "<unknown error>\n");
}
#endif